package com.punai.datapush.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.multi.ListValueMap;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.punai.common.core.domain.entity.SysPnDictionary;
import com.punai.common.core.page.TableDataInfo;
import com.punai.common.exception.ServiceException;
import com.punai.common.properties.FileUpPathConfig;
import com.punai.common.utils.NumberUtil;
import com.punai.common.utils.PageUtils;
import com.punai.common.utils.PnDictUtil;
import com.punai.common.utils.StringUtils;
import com.punai.common.utils.bean.BeanUtils;
import com.punai.customer.domain.bo.CusFeatureBo;
import com.punai.customer.domain.bo.FeatureRes;
import com.punai.customer.domain.contants.CusConstants;
import com.punai.customer.excelparse.ExcelListener;
import com.punai.datapush.domain.EcoFeeitemGuideprice;
import com.punai.datapush.domain.bo.EcoFeeitemGuidepriceBo;
import com.punai.datapush.domain.bo.FbGuidePriceBo;
import com.punai.datapush.domain.bo.GuidePriceUpdateBo;
import com.punai.datapush.domain.bo.GxGuidePriceBo;
import com.punai.datapush.domain.vo.EcoGuidePriceAddVo;
import com.punai.datapush.domain.vo.GuidePriceParseExcel;
import com.punai.datapush.domain.vo.GuidepriceExcelImpVo;
import com.punai.datapush.domain.vo.GuidepriceVo;
import com.punai.datapush.mapper.DataPushOtherMapper;
import com.punai.datapush.mapper.EcoFeeitemGuidepriceMapper;
import com.punai.datapush.service.IEcoFeeitemGuidepriceService;
import com.punai.file.domain.FileUploadFile;
import com.punai.file.service.UploadFileService;
import com.punai.standard.domain.StaFbChapter;
import com.punai.standard.domain.StaFbFee;
import com.punai.standard.domain.StaGxChapter;
import com.punai.standard.domain.StaGxFee;
import com.punai.standard.mapper.StaFbFeeMapper;
import com.punai.standard.mapper.StaGxFeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 指导价格库Service业务层处理
 *
 * @author zxw_
 * @date 2023-04-25
 */
@Service
public class EcoFeeitemGuidepriceServiceImpl extends ServiceImpl<EcoFeeitemGuidepriceMapper,EcoFeeitemGuideprice> implements IEcoFeeitemGuidepriceService
{
    @Autowired
    private EcoFeeitemGuidepriceMapper ecoFeeitemGuidepriceMapper;
    @Autowired
    private StaGxFeeMapper staGxFeeMapper;
    @Autowired
    private StaFbFeeMapper staFbFeeMapper;
    @Autowired
    private DataPushOtherMapper dataPushOtherMapper;
    @Autowired
    private UploadFileService uploadFileService;
    @Autowired
    private FileUpPathConfig fileUpPathConfig;

    private static final String GX_ROOT_ID = "GX_ROOT_ID";
    private static final String CB_ROOT_ID = "CB_ROOT_ID";

    @Override
    public TableDataInfo  datalist(GuidepriceVo vo) {
        TableDataInfo result = new TableDataInfo();
        // 决定调用的类
        String gxCbType = vo.getGxCbType();
        // 章节id
        String chapterId = vo.getChapterId();
        //
        String versionId = vo.getVersionId();
        // 是否 只查询 存在的数据
        boolean showExist = vo.isShowExist();

        if (StrUtil.equals(GX_ROOT_ID,gxCbType)) {
            List<String> chapterIds = new ArrayList<>();
            if (StrUtil.isNotEmpty(chapterId)) {
                chapterIds.add(chapterId);
                List<StaGxChapter> childByPid = dataPushOtherMapper.getChildByPid(chapterId, versionId);
                if (CollUtil.isNotEmpty(chapterIds)) {
                    chapterIds.addAll(childByPid.stream().map(StaGxChapter::getId).collect(Collectors.toList()));
                }
            }
            // 判定
            long total = 0L;
            List<StaGxFee> staGxFees = new ArrayList<>();
            if (showExist) {
                PageUtils.startPage();
                staGxFees = ecoFeeitemGuidepriceMapper.selectGxFee(vo, chapterIds);
                if (CollUtil.isEmpty(staGxFees)) {
                    return result;
                }
            } else {
                PageUtils.startPage();
                staGxFees = staGxFeeMapper.selectList(
                        Wrappers.<StaGxFee>lambdaQuery()
                                .in(chapterIds.size() > 0,StaGxFee::getChapterId, chapterIds)
                                .eq(StaGxFee::getVersionId, versionId)
                                .orderBy(true,true,StaGxFee::getCode)
                                .orderBy(true,true,StaGxFee::getOrderNum)
                );
                total = new PageInfo(staGxFees).getTotal();
            }

            List<String> feeCodes = staGxFees.stream().map(StaGxFee::getCode).collect(Collectors.toList());
            if (CollUtil.isEmpty(feeCodes)) {
                return result;
            }

            List<EcoFeeitemGuideprice> ecoFeeitemGuideprices = ecoFeeitemGuidepriceMapper.selectList(
                    Wrappers.<EcoFeeitemGuideprice>lambdaQuery()
                            .eq(EcoFeeitemGuideprice::getAddress, vo.getAddress())
                            .eq(EcoFeeitemGuideprice::getYt, vo.getYt())
                            .eq(EcoFeeitemGuideprice::getPeriodId, vo.getQc())
                            .in(EcoFeeitemGuideprice::getCode, feeCodes)
            );

            List<EcoFeeitemGuideprice> ecoFeeitemGuidepricesPJ = ecoFeeitemGuidepriceMapper.selectList(
                    Wrappers.<EcoFeeitemGuideprice>lambdaQuery()
                            .eq(EcoFeeitemGuideprice::getPeriodId, vo.getQc())
                            .eq(EcoFeeitemGuideprice::getDatafrom, "EvaluationSystem")
                            .in(EcoFeeitemGuideprice::getCode, feeCodes)
            );
            ecoFeeitemGuideprices.addAll(ecoFeeitemGuidepricesPJ);

            Map<String, List<EcoFeeitemGuideprice>> guidepriceMap = ecoFeeitemGuideprices.stream()
                    .collect(Collectors.groupingBy(EcoFeeitemGuideprice::getCode));
            // 组成结构
            List<GxGuidePriceBo> gxGuidePriceBos = new ArrayList<>();
            for (StaGxFee staGxFee : staGxFees) {
                String code = staGxFee.getCode();
                List<EcoFeeitemGuideprice> children = guidepriceMap.get(code);
                GxGuidePriceBo gxGuidePriceBo = new GxGuidePriceBo();
                gxGuidePriceBo.setId(staGxFee.getId());
                gxGuidePriceBo.setName(staGxFee.getName());
                gxGuidePriceBo.setCode(staGxFee.getCode());
                gxGuidePriceBo.setUnit(staGxFee.getUnit());
                if (CollUtil.isNotEmpty(children)) {
                    gxGuidePriceBo.setChildren(children);
                }
                gxGuidePriceBos.add(gxGuidePriceBo);
            }
            result.setRows(gxGuidePriceBos);
            result.setTotal(total);
        } else if (StrUtil.equals(CB_ROOT_ID,gxCbType)){
            List<String> chapterIds = new ArrayList<>();

            if (StrUtil.isNotEmpty(chapterId)) {
                chapterIds.add(chapterId);
                List<StaFbChapter> childByPid = dataPushOtherMapper.getFbChildByPid(chapterId, versionId);
                if (CollUtil.isNotEmpty(chapterIds)) {
                    chapterIds.addAll(childByPid.stream().map(StaFbChapter::getId).collect(Collectors.toList()));
                }
            }

            // 判定
            long total = 0L;
            List<StaFbFee> staFbFees = new ArrayList<>();
            if (showExist) {
                PageUtils.startPage();
                staFbFees = ecoFeeitemGuidepriceMapper.selectFbFee(vo, chapterIds);
                if (CollUtil.isEmpty(staFbFees)) {
                    return result;
                }
            } else {
                PageUtils.startPage();
                staFbFees = staFbFeeMapper.selectList(
                        Wrappers.<StaFbFee>lambdaQuery()
                                .in(chapterIds.size() > 0,StaFbFee::getChapterId, chapterIds)
                                .eq(StaFbFee::getVersionId, versionId)
                                .orderBy(true,true,StaFbFee::getCode)
                                .orderBy(true,true,StaFbFee::getOrderNum)
                );
                total = new PageInfo(staFbFees).getTotal();
            }


            List<String> feeCodes = staFbFees.stream().map(StaFbFee::getCode).collect(Collectors.toList());
            if (CollUtil.isEmpty(feeCodes)) {
                return result;
            }

            List<EcoFeeitemGuideprice> ecoFeeitemGuideprices = ecoFeeitemGuidepriceMapper.selectList(
                    Wrappers.<EcoFeeitemGuideprice>lambdaQuery()
                            .eq(EcoFeeitemGuideprice::getAddress, vo.getAddress())
                            .eq(EcoFeeitemGuideprice::getYt, vo.getYt())
                            .eq(EcoFeeitemGuideprice::getPeriodId, vo.getQc())
                            .in(EcoFeeitemGuideprice::getCode, feeCodes)
            );

            Map<String, List<EcoFeeitemGuideprice>> guidepriceMap = ecoFeeitemGuideprices.stream()
                    .collect(Collectors.groupingBy(EcoFeeitemGuideprice::getCode));
            // 组成结构
            List<FbGuidePriceBo> fbGuidePriceBos = new ArrayList<>();
            for (StaFbFee staGxFee : staFbFees) {
                String code = staGxFee.getCode();
                List<EcoFeeitemGuideprice> children = guidepriceMap.get(code);
                FbGuidePriceBo fbGuidePriceBo = new FbGuidePriceBo();
                fbGuidePriceBo.setId(staGxFee.getId());
                fbGuidePriceBo.setName(staGxFee.getName());
                fbGuidePriceBo.setCode(staGxFee.getCode());
                fbGuidePriceBo.setUnit(staGxFee.getUnit());
                if (CollUtil.isNotEmpty(children)) {
                    fbGuidePriceBo.setChildren(children);
                }
                fbGuidePriceBos.add(fbGuidePriceBo);
            }
            result.setRows(fbGuidePriceBos);
            result.setTotal(total);
        }

        return result;
    }

    @Override
    public List<FeatureRes> getStaFeeFeature(String id,String versionId, Long companyId) {
        List<CusFeatureBo> cusFeatureBos = dataPushOtherMapper.selectLinkDataAndEntityCopy(companyId,versionId,new String[]{id}, CusConstants.GX_TYPE);
        List<FeatureRes> featureResList = new ArrayList<>();
        if (CollUtil.isNotEmpty(cusFeatureBos)) {
            for (CusFeatureBo cusFeatureBo : cusFeatureBos) {
                FeatureRes featureRes = new FeatureRes();
                featureRes.setLinkId(cusFeatureBo.getLinkId());
                featureRes.setFeatureId(cusFeatureBo.getId());
                featureRes.setFeatureName(cusFeatureBo.getFeatureName());
                String featureValues = cusFeatureBo.getFeatureValues();
                featureRes.setFeatureValues(featureValues);
                featureRes.setItems(StrUtil.split(featureValues,"|"));
                featureRes.setInputEntry(cusFeatureBo.getIsInput());
                featureRes.setDefValue(cusFeatureBo.getDefValue());
                featureRes.setIsPrefix(cusFeatureBo.getIsPrefix());
                featureRes.setIsSubject(StringUtils.equals(cusFeatureBo.getIsSubject(),CusConstants.ENABLE_Y_TYPE));
                featureRes.setIsInput(cusFeatureBo.getIsInput());
                featureRes.setOrderNum(cusFeatureBo.getOrderNum());
                featureResList.add(featureRes);
            }
        }
        return featureResList;
    }

    @Override
    public boolean add(EcoGuidePriceAddVo vo) {
        String id = vo.getId();
        String left = vo.getLeft();
        String right = vo.getRight();
        BigDecimal notaxprice = vo.getNotaxprice();
        BigDecimal taxprice = vo.getTaxprice();
        BigDecimal sl = vo.getSl();
        String spec = vo.getSpec();
        String code = vo.getCode();
        String name = vo.getName();
        String unit = vo.getUnit();
        String address = vo.getAddress();
        String yt = vo.getYt();
        String qc = vo.getQc();
        //
        if (StrUtil.isEmpty(id)) {
          // 新增
            EcoFeeitemGuideprice ecoFeeitemGuideprice = new EcoFeeitemGuideprice();
            ecoFeeitemGuideprice.setCode(code);
            ecoFeeitemGuideprice.setPeriodId(qc);
            ecoFeeitemGuideprice.setUnit(unit);
            ecoFeeitemGuideprice.setYt(yt);
            ecoFeeitemGuideprice.setAddress(address);
            ecoFeeitemGuideprice.setPrefixSpec(left);
            ecoFeeitemGuideprice.setSuffixSpec(right);
            ecoFeeitemGuideprice.setSpecDetail(spec);
            ecoFeeitemGuideprice.setName(name);
            ecoFeeitemGuideprice.setSpecName(left + name + right);
            ecoFeeitemGuideprice.setNotaxprice(notaxprice);
            ecoFeeitemGuideprice.setSl(sl);
            ecoFeeitemGuideprice.setTaxprice(taxprice);
            ecoFeeitemGuideprice.setOrderNum(getMaxPxByCode(code) + 1);

            if (existDuplication(ecoFeeitemGuideprice)) {
                throw new ServiceException("编码" + code + "特征 " + ecoFeeitemGuideprice.getSpecName() + " 已存在");
            }
            ecoFeeitemGuidepriceMapper.insert(ecoFeeitemGuideprice);
        } else {
            // 修改
            EcoFeeitemGuideprice ecoFeeitemGuideprice = ecoFeeitemGuidepriceMapper.selectById(id);
            if (ecoFeeitemGuideprice == null) {
                throw new ServiceException("数据不存在");
            }
            ecoFeeitemGuideprice.setPrefixSpec(left);
            ecoFeeitemGuideprice.setSuffixSpec(right);
            ecoFeeitemGuideprice.setSpecDetail(spec);
            ecoFeeitemGuideprice.setSpecName(left + name + right);
            ecoFeeitemGuideprice.setNotaxprice(notaxprice);
            ecoFeeitemGuideprice.setSl(sl);
            ecoFeeitemGuideprice.setTaxprice(taxprice);

            if (existDuplication(ecoFeeitemGuideprice)) {
                throw new ServiceException("编码" + code + "特征 " + ecoFeeitemGuideprice.getSpecName() + " 已存在");
            }
            ecoFeeitemGuidepriceMapper.updateById(ecoFeeitemGuideprice);
        }
        return true;
    }

    @Override
    public GuidePriceUpdateBo getInfo(String id) {
        EcoFeeitemGuideprice guideprice = getById(id);
        String specDetail = guideprice.getSpecDetail();
        List<FeatureRes> featureRes = JSONUtil.parseArray(specDetail).toList(FeatureRes.class);
        GuidePriceUpdateBo convert = GuidePriceUpdateBo.convert(guideprice);
        convert.setFeatureResList(featureRes);
        return convert;
    }

    @Override
    public boolean deleteInfo(String id) {
        int i = ecoFeeitemGuidepriceMapper.deleteById(id);
        return i > 0;
    }

    @Override
    public List<EcoFeeitemGuidepriceBo> selectEcoFeeitemGuidepriceList(GuidepriceVo vo) {
        // 决定调用的类
        String gxCbType = vo.getGxCbType();
        // 章节id
        String chapterId = vo.getChapterId();
        //
        String versionId = vo.getVersionId();
        // 是否 只查询 存在的数据
        boolean showExist = vo.isShowExist();
        if (StrUtil.equals(GX_ROOT_ID,gxCbType)) {
            List<String> chapterIds = new ArrayList<>();
            if (StrUtil.isNotEmpty(chapterId)) {
                chapterIds.add(chapterId);
                List<StaGxChapter> childByPid = dataPushOtherMapper.getChildByPid(chapterId, versionId);
                if (CollUtil.isNotEmpty(chapterIds)) {
                    chapterIds.addAll(childByPid.stream().map(StaGxChapter::getId).collect(Collectors.toList()));
                }
            }
            // 判定
            long total = 0L;
            List<StaGxFee> staGxFees = new ArrayList<>();
            if (showExist) {
                staGxFees = ecoFeeitemGuidepriceMapper.selectGxFee(vo, chapterIds);
            } else {
                staGxFees = staGxFeeMapper.selectList(
                        Wrappers.<StaGxFee>lambdaQuery()
                                .in(chapterIds.size() > 0,StaGxFee::getChapterId, chapterIds)
                                .eq(StaGxFee::getVersionId, versionId)
                                .orderBy(true,true,StaGxFee::getCode)
                                .orderBy(true,true,StaGxFee::getOrderNum)
                );
            }

            List<String> feeCodes = staGxFees.stream().map(StaGxFee::getCode).collect(Collectors.toList());
            if (CollUtil.isEmpty(feeCodes)) {
                return new ArrayList<>();
            }

            List<EcoFeeitemGuideprice> ecoFeeitemGuideprices = ecoFeeitemGuidepriceMapper.selectList(
                    Wrappers.<EcoFeeitemGuideprice>lambdaQuery()
                            .eq(EcoFeeitemGuideprice::getAddress, vo.getAddress())
                            .eq(EcoFeeitemGuideprice::getYt, vo.getYt())
                            .eq(EcoFeeitemGuideprice::getPeriodId, vo.getQc())
                            .in(EcoFeeitemGuideprice::getCode, feeCodes)
            );

            Map<String, List<EcoFeeitemGuideprice>> guidepriceMap = ecoFeeitemGuideprices.stream()
                    .collect(Collectors.groupingBy(EcoFeeitemGuideprice::getCode));
            // 组成结构
            List<GxGuidePriceBo> gxGuidePriceBos = new ArrayList<>();
            for (StaGxFee staGxFee : staGxFees) {
                String code = staGxFee.getCode();
                List<EcoFeeitemGuideprice> children = guidepriceMap.get(code);
                GxGuidePriceBo gxGuidePriceBo = new GxGuidePriceBo();
                gxGuidePriceBo.setId(staGxFee.getId());
                gxGuidePriceBo.setName(staGxFee.getName());
                gxGuidePriceBo.setCode(staGxFee.getCode());
                gxGuidePriceBo.setUnit(staGxFee.getUnit());
                if (CollUtil.isNotEmpty(children)) {
                    gxGuidePriceBo.setChildren(children);
                }
                gxGuidePriceBos.add(gxGuidePriceBo);
            }

            // gxGuidePriceBos 转化成 EcoFeeitemGuidepriceBo
            List<EcoFeeitemGuidepriceBo> ecoFeeitemGuidepriceBos = new ArrayList<>();
            for (GxGuidePriceBo gxGuidePriceBo : gxGuidePriceBos) {
                EcoFeeitemGuidepriceBo ecoFeeitemGuidepriceBo = new EcoFeeitemGuidepriceBo();
                BeanUtils.copyBeanProp(ecoFeeitemGuidepriceBo,gxGuidePriceBo);
                ecoFeeitemGuidepriceBo.setSpecName(gxGuidePriceBo.getName());
                ecoFeeitemGuidepriceBos.add(ecoFeeitemGuidepriceBo);
                List<EcoFeeitemGuideprice> children = gxGuidePriceBo.getChildren();
                if (CollUtil.isNotEmpty(children)) {
                    for (EcoFeeitemGuideprice child : children) {
                        EcoFeeitemGuidepriceBo childrenBo = new EcoFeeitemGuidepriceBo();
                        BeanUtils.copyBeanProp(childrenBo,child);
                        childrenBo.setTz(child.getPrefixSpec() + child.getSuffixSpec());
                        SysPnDictionary dictionary = PnDictUtil.getDictionary(child.getYt());
                        childrenBo.setYt(dictionary != null ? dictionary.getName() : "");
                        ecoFeeitemGuidepriceBos.add(childrenBo);
                    }
                }
            }
            return ecoFeeitemGuidepriceBos;
        }else if (StrUtil.equals(CB_ROOT_ID,gxCbType)){
            List<String> chapterIds = new ArrayList<>();

            if (StrUtil.isNotEmpty(chapterId)) {
                chapterIds.add(chapterId);
                List<StaFbChapter> childByPid = dataPushOtherMapper.getFbChildByPid(chapterId, versionId);
                if (CollUtil.isNotEmpty(chapterIds)) {
                    chapterIds.addAll(childByPid.stream().map(StaFbChapter::getId).collect(Collectors.toList()));
                }
            }

            // 判定
            List<StaFbFee> staFbFees = new ArrayList<>();
            if (showExist) {
                PageUtils.startPage();
                staFbFees = ecoFeeitemGuidepriceMapper.selectFbFee(vo, chapterIds);
                if (CollUtil.isEmpty(staFbFees)) {
                    return new ArrayList<>();
                }
            } else {
                PageUtils.startPage();
                staFbFees = staFbFeeMapper.selectList(
                        Wrappers.<StaFbFee>lambdaQuery()
                                .in(chapterIds.size() > 0,StaFbFee::getChapterId, chapterIds)
                                .eq(StaFbFee::getVersionId, versionId)
                                .orderBy(true,true,StaFbFee::getCode)
                                .orderBy(true,true,StaFbFee::getOrderNum)
                );
            }


            List<String> feeCodes = staFbFees.stream().map(StaFbFee::getCode).collect(Collectors.toList());
            if (CollUtil.isEmpty(feeCodes)) {
                return new ArrayList<>();
            }

            List<EcoFeeitemGuideprice> ecoFeeitemGuideprices = ecoFeeitemGuidepriceMapper.selectList(
                    Wrappers.<EcoFeeitemGuideprice>lambdaQuery()
                            .eq(EcoFeeitemGuideprice::getAddress, vo.getAddress())
                            .eq(EcoFeeitemGuideprice::getYt, vo.getYt())
                            .eq(EcoFeeitemGuideprice::getPeriodId, vo.getQc())
                            .in(EcoFeeitemGuideprice::getCode, feeCodes)
            );

            Map<String, List<EcoFeeitemGuideprice>> guidepriceMap = ecoFeeitemGuideprices.stream()
                    .collect(Collectors.groupingBy(EcoFeeitemGuideprice::getCode));
            // 组成结构
            List<FbGuidePriceBo> fbGuidePriceBos = new ArrayList<>();
            for (StaFbFee staGxFee : staFbFees) {
                String code = staGxFee.getCode();
                List<EcoFeeitemGuideprice> children = guidepriceMap.get(code);
                FbGuidePriceBo fbGuidePriceBo = new FbGuidePriceBo();
                fbGuidePriceBo.setId(staGxFee.getId());
                fbGuidePriceBo.setName(staGxFee.getName());
                fbGuidePriceBo.setCode(staGxFee.getCode());
                fbGuidePriceBo.setUnit(staGxFee.getUnit());
                if (CollUtil.isNotEmpty(children)) {
                    fbGuidePriceBo.setChildren(children);
                }
                fbGuidePriceBos.add(fbGuidePriceBo);
            }

            // gxGuidePriceBos 转化成 EcoFeeitemGuidepriceBo
            List<EcoFeeitemGuidepriceBo> ecoFeeitemGuidepriceBos = new ArrayList<>();
            for (FbGuidePriceBo gxGuidePriceBo : fbGuidePriceBos) {
                EcoFeeitemGuidepriceBo ecoFeeitemGuidepriceBo = new EcoFeeitemGuidepriceBo();
                BeanUtils.copyBeanProp(ecoFeeitemGuidepriceBo,gxGuidePriceBo);
                ecoFeeitemGuidepriceBo.setSpecName(gxGuidePriceBo.getName());
                ecoFeeitemGuidepriceBos.add(ecoFeeitemGuidepriceBo);

                List<EcoFeeitemGuideprice> children = gxGuidePriceBo.getChildren();
                if (CollUtil.isNotEmpty(children)) {
                    for (EcoFeeitemGuideprice child : children) {
                        EcoFeeitemGuidepriceBo childrenBo = new EcoFeeitemGuidepriceBo();
                        BeanUtils.copyBeanProp(childrenBo,child);
                        childrenBo.setTz(child.getPrefixSpec() + child.getSuffixSpec());
                        SysPnDictionary dictionary = PnDictUtil.getDictionary(child.getYt());
                        childrenBo.setYt(dictionary != null ? dictionary.getName() : "");
                        ecoFeeitemGuidepriceBos.add(childrenBo);
                    }
                }
            }
            return ecoFeeitemGuidepriceBos;
        }
        return null;
    }



    @Override
    @Transactional
    public String importData(GuidepriceExcelImpVo guidepriceExcelImpVo) {
        String fileId = guidepriceExcelImpVo.getFileId();
        FileUploadFile uploadFile = uploadFileService.getById(fileId);
        String fileName = uploadFile.getFileName();
        String filePath = uploadFile.getFilePath();

        // 校验格式
        String temp[]=fileName.split("\\.");
        String fileNameNow=temp[temp.length-1];
        if(!StringUtils.equals(fileNameNow,"xlsx") && !StringUtils.equals(fileNameNow,"xls")){
            throw new ServiceException("请上传excel文件!");
        }
        String excelPath = fileUpPathConfig.getBasePath() + "/" + filePath;
        // 读取excel
        InputStream inputStream = FileUtil.getInputStream(excelPath);
        if (inputStream == null) {
            throw new ServiceException("对应文件不存在,请联系管理员");
        }
        //监视器
        ExcelListener listener = new ExcelListener();

        ExcelReader excelReader = EasyExcel.read(inputStream, listener).build();
        // 第一个sheet读取类型
        ReadSheet readSheet1 = EasyExcel.readSheet(0).head(GuidePriceParseExcel.class).headRowNumber(1).build();
        // 开始读取第一个sheet
        excelReader.read(readSheet1);
        List<GuidePriceParseExcel> excelList = listener.getDataList();
        StringBuilder stringBuilder = new StringBuilder();

        int size = excelList.size();

        int pageSize = 2000;
        int pageNumber = (int) Math.ceil((double) size / (double) pageSize);

        for (int i = 0; i < pageNumber; i++) {
            List<GuidePriceParseExcel> subList = excelList.subList(i * pageSize, Math.min((i + 1) * pageSize, size));
            List<String> codes = new ArrayList<>();
            List<EcoFeeitemGuideprice> guidepricesList = new ArrayList<>();

            for (GuidePriceParseExcel guidePriceParseExcel : subList) {
                i ++ ;
                boolean isOk = true;
                if (StrUtil.isBlank(guidePriceParseExcel.getCode())) {
                    stringBuilder.append("第").append(i).append("行,编码不能为空 ");
                    isOk = false;
                }
                if (StrUtil.isBlank(guidePriceParseExcel.getName())) {
                    stringBuilder.append("第").append(i).append("行,名称不能为空 ");
                    isOk = false;
                }
                if (isOk) {
                    codes.add(guidePriceParseExcel.getCode());
                }
            }
            ListValueMap<String,String> codeNamesMap = new ListValueMap<>();
            if (CollUtil.isNotEmpty(codes)) {
                List<EcoFeeitemGuideprice> ecoFeeitemGuideprices = ecoFeeitemGuidepriceMapper.selectList(
                        Wrappers.<EcoFeeitemGuideprice>lambdaQuery()
                                .select(EcoFeeitemGuideprice::getCode,EcoFeeitemGuideprice::getSpecName)
                                .in(EcoFeeitemGuideprice::getCode, codes)
                                .eq(EcoFeeitemGuideprice::getPeriodId, guidepriceExcelImpVo.getQc())
                                .eq(EcoFeeitemGuideprice::getYt, guidepriceExcelImpVo.getYt())
                                .eq(EcoFeeitemGuideprice::getAddress, guidepriceExcelImpVo.getAddress())
                );
                for (EcoFeeitemGuideprice ecoFeeitemGuideprice : ecoFeeitemGuideprices) {
                    codeNamesMap.putValue(ecoFeeitemGuideprice.getCode(),ecoFeeitemGuideprice.getSpecName());
                }
            }
            int j = 0;
            Map<String,Integer> codeCountMap = new HashMap<>();
            for (GuidePriceParseExcel guidePriceParseExcel : subList) {
                j ++ ;
                String code = guidePriceParseExcel.getCode();
                List<String> names = codeNamesMap.get(code);
                String name = guidePriceParseExcel.getName();
                String ls = guidePriceParseExcel.getLeftSpec();
                String rs = guidePriceParseExcel.getRightSpec();

                if (StrUtil.isNotBlank(ls)) {
                    ls = "(" + ls + ")";
                } else {
                    ls = "";
                }
                if (StrUtil.isNotBlank(rs)) {
                    rs = "(" + rs + ")";
                } else {
                    rs = "";
                }
                String specName = ls + name + rs;

                Integer integer = codeCountMap.get(specName);
                if (integer != null) {
                    stringBuilder.append("第").append(j).append("行,与第").append(integer).append("行存在的特征重复 ");
                    continue;
                }
                if (CollUtil.isNotEmpty(names) && names.contains(specName)) {
                    stringBuilder.append("第").append(j).append("行,与数据库存在的特征重复 ");
                } else {
                    EcoFeeitemGuideprice guideprice = new EcoFeeitemGuideprice();
                    guideprice.setNotaxprice(guidePriceParseExcel.getNotaxprice());
                    guideprice.setSl(guidePriceParseExcel.getSl());
                    guideprice.setTaxprice(guidePriceParseExcel.getTaxprice());
                    guideprice.setCode(code);
                    Map<String, Object> calcPrice = calcPrice(guideprice);

                    if (calcPrice.containsKey("error")) {
                        stringBuilder.append(calcPrice.get("error"));
                        continue;
                    }
                    guideprice.setCreateType("2");
                    guideprice.setPeriodId(guidepriceExcelImpVo.getQc());
                    guideprice.setYt(guidepriceExcelImpVo.getYt());
                    guideprice.setAddress(guidepriceExcelImpVo.getAddress());
                    guideprice.setSpecName(specName);
                    guideprice.setOrderNum(getMaxPxByCode(code) + 1);
                    guideprice.setName(name);
                    guideprice.setUnit(guidePriceParseExcel.getUnit());
                    guideprice.setPrefixSpec(ls);
                    guideprice.setSuffixSpec(rs);
                    codeCountMap.put(specName,j);
                    guidepricesList.add(guideprice);
                }
            }
            if (guidepricesList.size() > 0 ) {
                ecoFeeitemGuidepriceMapper.insertBatchSomeColumn(guidepricesList);
                guidepricesList.clear();
            }
        }
        return stringBuilder.toString();
    }

    private Map<String, Object> calcPrice(EcoFeeitemGuideprice guideprice) {
        String code = guideprice.getCode();
        BigDecimal priceWithNotTax = guideprice.getNotaxprice();
        BigDecimal tax = guideprice.getSl();
        BigDecimal priceWithTax = guideprice.getTaxprice();
        Map<String, Object> map = new HashMap<>();
        if((tax == null && priceWithNotTax == null)
                ||(tax == null && priceWithTax == null)
                || (priceWithNotTax == null && priceWithTax == null)){

            map.put("error", "文档中 费用项编码" + code + ", 含税价，除税价，税率至少有两个不为空!");
            return map;
        }

        if (NumberUtil.isEmpty(priceWithNotTax)) {
            priceWithNotTax = priceWithTax.divide(new BigDecimal(1).add(tax), 4, RoundingMode.HALF_DOWN);
        }
        if (NumberUtil.isEmpty(priceWithTax)) {
            priceWithTax = priceWithNotTax.multiply(new BigDecimal(1).add(tax)).setScale(4, RoundingMode.HALF_UP);
        }
        if (NumberUtil.isEmpty(tax)) {
            tax = NumberUtil.divide(priceWithTax, 4, BigDecimal.ROUND_DOWN, priceWithNotTax).subtract(BigDecimal.ONE);
        }
        if (NumberUtil.compareTo(priceWithNotTax, priceWithTax) == 1) {
            map.put("error", "文档中 费用项编码" + code + ", 存在不含税大于含税!");
        }
        guideprice.setTaxprice(priceWithTax);
        guideprice.setNotaxprice(priceWithNotTax);
        guideprice.setSl(tax);
        return map;
    }

    private Integer getMaxPxByCode(String code) {
        EcoFeeitemGuideprice ecoFeeitemGuideprice = ecoFeeitemGuidepriceMapper.selectOne(
                Wrappers.<EcoFeeitemGuideprice>lambdaQuery()
                        .eq(EcoFeeitemGuideprice::getCode, code)
                        .orderByDesc(EcoFeeitemGuideprice::getOrderNum)
                        .last("limit 1")

        );
        if (ecoFeeitemGuideprice == null) {
            return 0;
        }
        return ecoFeeitemGuideprice.getOrderNum();
    }

    private boolean existDuplication(EcoFeeitemGuideprice guideprice) {
        EcoFeeitemGuideprice ecoFeeitemGuideprice = ecoFeeitemGuidepriceMapper.selectOne(
                Wrappers.<EcoFeeitemGuideprice>lambdaQuery()
                        .eq(EcoFeeitemGuideprice::getCode, guideprice.getCode())
                        .eq(EcoFeeitemGuideprice::getPeriodId, guideprice.getPeriodId())
                        .eq(EcoFeeitemGuideprice::getAddress, guideprice.getAddress())
                        .eq(EcoFeeitemGuideprice::getYt, guideprice.getYt())
                        .eq(EcoFeeitemGuideprice::getPrefixSpec, guideprice.getPrefixSpec())
                        .eq(EcoFeeitemGuideprice::getSuffixSpec, guideprice.getSuffixSpec())
        );
        return ecoFeeitemGuideprice != null;
    }


}
